#include <iostream>
#include <string>

// 简单工厂模式 计算器
// 计算操作抽象类
class Operation{
    public:
    void set(double numberA, double numberB) {
        numberA_ = numberA;
        numberB_ = numberB;
    }
    virtual ~Operation() {
        std::cout << "调用父类析构函数" << std::endl;
    }
    virtual double  GetResult() {
            return 0;
        }
    protected:
        double numberA_;
        double numberB_;

};

// 加法计算子类
class OperationAdd : public Operation {
    public:
    virtual ~OperationAdd() {
        std::cout << "调用+类析构函数" << std::endl;
    }
    double GetResult() {
            return numberA_ + numberB_;
        }
};

// 减法计算子类
class OperationSub : public Operation {
    public:
    virtual ~OperationSub() {
        std::cout << "调用-类析构函数" << std::endl;
    }
    double GetResult() {
            return numberA_ - numberB_;
        }
};

// 乘法计算子类
class OperationPro : public Operation {
    public:
    virtual ~OperationPro() {
        std::cout << "调用*类析构函数" << std::endl;
    }
    double GetResult() {
            return numberA_ * numberB_;
        }
};

// 除法计算子类
class OperationDiv : public Operation {
    public:
    virtual ~OperationDiv() {
        std::cout << "调用/类析构函数" << std::endl;
    }
    double GetResult() {
            if(numberB_ != 0) {
                return numberA_ / numberB_;
            }
            else {
                return __DBL_MAX__;
            }
        }
};

// 计算操作工程类
class OperationFactory {
    public:
    ~OperationFactory() {
        if(oper_ != nullptr) {
            delete oper_;
            oper_ = nullptr;
        }
    }
    Operation* OperationInterface(std::string operate,double numberA,double numberB) {
        if(operate == "+") {
            oper_ = new OperationAdd();
        }
        else if(operate == "-") {
            oper_ = new OperationSub();
        }
        else if(operate == "*") {
            oper_ = new OperationPro();
        }
        else if(operate == "/") {
            oper_ = new OperationDiv();
        }
        oper_->set(numberA,numberB);
        return oper_;
    }
    private:
    Operation* oper_ = nullptr;
};

int main() {
    std::cout << "Hello design patterns" << std::endl;
    OperationFactory OF;
    Operation* oper = OF.OperationInterface("-",10.0,2.8);
    double res = oper->GetResult();
    double res = oper->GetResult();
    std::cout << "res = " << res << std::endl;
    return 0;
}